import React, {Component} from 'react';
import ReactDOM, {findDOMNode} from 'react-dom';

/*
props上:
  onOpen(node)
  beforeClose(node, resetFn)
  onClose()
  onUpdate()
  openByClickOn node
*/

export default class Portal extends Component {
  constructor (props) {
    super(props);
    this.state = {
      active: false
    };
    this.portal = null;
    this.node = null;
  }
  openPortal (props = this.props) {
    this.setState({active: true});
    this.renderPortal(props);
    this.props.onOpen(this.node);
  }
  // 关闭组件
  closePortal (isUnmounted = false) {
    // 重置portal的状态
    const resetPortalState = () => {
      if (this.node) {
        // 节点存在
        // 删除节点
        ReactDOM.unmountComponentAtNode(this.node);
        document.body.removeChild(this.node);
      }
      this.portal = null;
      this.node = null;
      if (isUnmounted !== true) {
        this.setState({active: false});
      }
    };

    if (this.state.active) {
      if (this.props.beforeClose) {
        // 关闭前函数存在
        this.props.beforeClose(this.node, resetPortalState);
      } else {
        // 关闭前函数不存在，直接重置状态
        resetPortalState();
      }
      // 执行props上的关闭操作
      this.props.onClose();
    }
  }
  // 渲染portal
  renderPortal(props) {
    if (!this.node) {
      // node不存在，创建node插入
      this.node = document.createElement('div');
      // 在节点增加到DOM前，执行CSS防止无效重绘
      this.applyClassNameAndStyle(props);
      document.body.appendChild(this.node);
    } else {
      // 当新props传下来的时候，更新Css
      this.applyClassNameAndStyle(props);
    }

    let children = props.children;
    if (typeof children.type === 'function') {
      children = React.cloneElement(children, {
        closePortal: this.closePortal
      });
    }
    this.portal = ReactDOM.unstable_renderSubtreeIntoContainer(
      this,
      children,
      this.node,
      this.props.onUpdate
    )
  }
  applyClassNameAndStyle (props) {
    this.node.className = props.className;
    if (props.style) {
      for (let attr in props.style) {
        this.node.style[attr] = props.style[attr];
      }
    }
  }
  render () {
    if (this.props.openByClickOn) {
      return React.cloneElement(this.props.openByClickOn, {onClick: this.handleWrapperClick});
    }
    return null;
  }
}
